package com.jk.wh.service.impl;


import com.alibaba.fastjson.JSONObject;
import com.jk.*;

import com.jk.wh.dao.EsDao;
import com.jk.wh.dao.MovieDao;
import com.jk.wh.service.MovieService;

import org.apache.commons.lang.StringUtils;
import org.elasticsearch.action.search.SearchRequestBuilder;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.Client;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.MatchQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.ArrayList;

import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicReference;


@Service
public class MovieServiceImpl implements MovieService {

    @Autowired
    private MovieDao movieDao;
    @Autowired
    private ElasticsearchTemplate elasticsearchTemplate;
    @Autowired
    private EsDao esDao;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private MongoTemplate mongoTemplate;

    //电影查询（各种条查）
    @Override
    public List<MovieBean> queryMovie(MovieBean movie) {
        List<MovieBean> movieList=  movieDao.queryMovie(movie);
        List<MovieBean> list=  new ArrayList<>();
        esDao.deleteAll();
       for (MovieBean mm: movieList) {
            esDao.save(mm);
        }
        Client client = elasticsearchTemplate.getClient();
        SearchRequestBuilder searchRequestBuilder = client.prepareSearch("lookmovie").setTypes("movie");
        BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
        if(!StringUtils.isEmpty(movie.getMovieName())){
            MatchQueryBuilder movieName = QueryBuilders.matchQuery("movieName",movie.getMovieName());
            boolQueryBuilder.must(movieName);
        }
        if (movie.getStatus()!=null){
            MatchQueryBuilder status = QueryBuilders.matchQuery("status",movie.getStatus());
            boolQueryBuilder.must(status);
        }
        if (movie.getTypename()!=null && !movie.getTypename().equals("-1")){
            MatchQueryBuilder movieType = QueryBuilders.matchQuery("typename",movie.getTypename());
            boolQueryBuilder.must(movieType);
        }
        if(movie.getMoviestate()!=null && !movie.getMoviestate().equals("空")){
            MatchQueryBuilder moviestate = QueryBuilders.matchQuery("moviestate",movie.getMoviestate());
            boolQueryBuilder.must(moviestate);
        }
        searchRequestBuilder.setQuery(boolQueryBuilder);
        //排序
        if (movie.getLook()!=null && movie.getLook()==1) {
            searchRequestBuilder.addSort("ticketCount", SortOrder.DESC);
        }
        if (movie.getLook()!=null && movie.getLook()==2) {
            searchRequestBuilder.addSort("filmSchedule", SortOrder.DESC);
        }
        if (movie.getLook()!=null && movie.getLook()==3) {
            searchRequestBuilder.addSort("movieGrade", SortOrder.DESC);
        }
        //设置高亮
        HighlightBuilder highlightBuilder = new HighlightBuilder();
        highlightBuilder.field("movieName");//设置高亮字段
        highlightBuilder.preTags("<font color='red'>");
        highlightBuilder.postTags("</font>");
        searchRequestBuilder.highlighter(highlightBuilder);
        //获取到所有搜索出的结果 也叫所有命中对象
        SearchResponse searchResponse = searchRequestBuilder.get();
        SearchHits hits = searchResponse.getHits();
        Iterator<SearchHit> iterator = hits.iterator();
        while (iterator.hasNext()){
            SearchHit next = iterator.next();
            String sourceAsString = next.getSourceAsString();
            MovieBean movieBean = JSONObject.parseObject(sourceAsString, MovieBean.class);
            //获取到所有高亮字段结果集
            Map<String, HighlightField> highlightFields = next.getHighlightFields();
            //获取姓名的高亮结果
            HighlightField name = highlightFields.get("movieName");
            if(name!=null){
                movieBean.setMovieName(name.getFragments()[0].toString());
            }
            list.add(movieBean);
        }
        return list;
    }
    /*
     * @Author: xz
     * @Description: 查询正在热映的电影
     * @Date: 2021/5/21 14:53
     * @Param:[]
     * @Return: java.util.List<com.jk.MovieBean>
     **/
    @Override
    public List<MovieBean> getRadientMovie() {
        return movieDao.getRadientMovie();
    }
    /*
    * @Author: xz
    * @Description: 查询待上映的电影
    * @Date: 2021/5/21 15:16
    * @Param:[]
    * @Return: java.util.List<com.jk.MovieBean>
    **/
    @Override
    public List<MovieBean> waitMovie() {
        return movieDao.waitMovie();
    }
    /*
    * @Author: xz
    * @Description: 查询最受期待电影前10
    * @Date: 2021/5/21 16:06
    * @Param:[]
    * @Return: java.util.List<com.jk.MovieBean>
    **/
    @Override
    public List<MovieBean> expectMovie() {
        return movieDao.expectMovie();
    }
    /*
    * @Author: xz
    * @Description: 查询前10个高评分电影
    * @Date: 2021/5/21 19:05
    * @Param:[]
    * @Return: java.util.List<com.jk.MovieBean>
    **/
    @Override
    public List<MovieBean> getScore() {
        return movieDao.getScore();
    }
    /*
     * @Author: xz
     * @Description: 查询已上映的总条数
     * @Date: 2021/5/24 9:56
     * @Param:
     * @Return:
     **/
    @Override
    public Integer getMovieCount() {
        return movieDao.getMovieCount();
    }
    /*
     * @Author: xz
     * @Description: 查询待上映的总条数
     * @Date: 2021/5/24 9:56
     * @Param:
     * @Return:
     **/
    @Override
    public Integer getMovieCount2() {
        return movieDao.getMovieCount2();
    }

    @Override
    public List<CarouselBean> getCarousel() {
        return movieDao.getCarousel();
    }
    //查询类型表
    @Override
    public List<MovieTypeBean> getType() {
        return movieDao.getType();
    }
    //查询es条查总条数
    @Override
    public Integer getMovieCountByStatus(String movieName) {
        return movieDao.getMovieCountByStatus(movieName);
    }

    //生成未支付订单存redis
    @Override
    public void saveRedis(OrderBean order) {

        String hashkey = "orderList";
        String key = "userphone_"+123;
        order.setCinemaId(1);
        order.setCinemaName("哈哈哈");
        order.setHallId(1);
        order.setMovieName("hhh");
        order.setOrderId("11111111111");
        List<OrderBean> orderlist = new ArrayList<OrderBean>();
        if (redisTemplate.opsForHash().hasKey(hashkey,key)){//存在
            orderlist = (List<OrderBean>) redisTemplate.opsForHash().get(hashkey, key);
            orderlist.add(order);
            redisTemplate.opsForHash().put(hashkey,key,orderlist);
        }else{
            orderlist.add(order);
            redisTemplate.opsForHash().put(hashkey,key,orderlist);
        }
    }
    /*
    * @Author: xz
    * @Description:查询热播电影
    * @Date: 2021/5/26 15:18
    * @Param:[mm]
    * @Return: java.util.List<com.jk.MovieBean>
    **/
    @Override
    public List<MovieBean> queryHitTv(MovieBean mm) {
        return movieDao.queryHitTv(mm);
    }
    /*
    * @Author: xz
    * @Description: 获取票房排行前五名
    * @Date: 2021/5/26 16:25
    * @Param:[]
    * @Return: java.util.List<com.jk.MovieBean>
    **/
    @Override
    public List<MovieBean> getMoney() {
        return movieDao.getMoney();
    }

    /**
    * @Author: wh
    * @Description: 删除redis 存入mongodb
    * @Date: 2021/5/26 16:40
    * @Param:[orderId]
    * @Return: void
    **/
    @Override
    public void saveOrder(OrderBean order) {

        String orderKey = "orderList";
        String orderHashKey = "userphone_"+order.getPhone();
        List<OrderBean> orderlist = (List<OrderBean>) redisTemplate.opsForHash().get(orderKey, orderHashKey);
        //删除已支付订单
        AtomicReference<OrderBean> order2 = new AtomicReference<>(new OrderBean());
        orderlist.removeIf(ele ->{
            if (ele.getOrderId().equals(order.getOrderId())){
                order2.set(ele);
                return true;
            }else{
                return false;
            }
        });
        redisTemplate.opsForHash().put(orderKey,orderHashKey,orderlist);
        //支付完成订单存入mongodb
        OrderBean orderBean = order2.get();
        mongoTemplate.save(orderBean);
        //修改座位状态
        String seats = orderBean.getSeats();
        String[] split = seats.split(",");
        for (int i = 0; i <split.length ; i++) {
            char[] chars = split[i].toCharArray();
            movieDao.updateSeats(chars[0],chars[3],orderBean);
        }

    }
    //查询影院
    @Override
    public List<CinemaBean> queryCinemaAll(CinemaBean cc) {
        return movieDao.queryCinemaAll(cc);
    }
    //根据id查询影院
    @Override
    public CinemaBean buyTicketById(Integer cinemaId) {
        return movieDao.buyTicketById(cinemaId);
    }
    /*
    * @Author: xz
    * @Description:根据影院id查询影院对应的电影
    * @Date: 2021/5/27 21:46
    * @Param:[cinemaId]
    * @Return: java.util.List<com.jk.MovieBean>
    **/
    @Override
    public List<MovieBean> queryMovieAllById(Integer cinemaId) {
        return movieDao.queryMovieAllById(cinemaId);
    }
    /*
    * @Author: xz
    * @Description: 根据影院id 电影id查看观影时间
    * @Date: 2021/5/28 17:41
    * @Param:[cinemaId, movieId]
    * @Return: java.util.List<com.jk.MovieBean>
    **/
    @Override
    public List<MovieBean> getMovieCinemaById(Integer cinemaId, Integer movieId, String date) {
        return movieDao.getMovieCinemaById(cinemaId,movieId,date);
    }
    /*
    * @Author: xz
    * @Description: 根据影院id 电影id查询影院对应的电影
    * @Date: 2021/5/28 20:58
    * @Param:[cinemaId, movieId]
    * @Return: com.jk.MovieBean
    **/
    @Override
    public MovieBean getMovies2(Integer cinemaId, Integer movieId) {
        return movieDao.getMovies2(cinemaId,movieId);
    }
    /*
    * @Author: xz
    * @Description: 动态查询排片时间
    * @Date: 2021/5/30 10:32
    * @Param:[cinemaId, movieId]
    * @Return: java.util.List<com.jk.ProgramBean>
    **/
    @Override
    public List<ProgramBean> getDate(Integer cinemaId, Integer movieId) {
        return movieDao.getDate(cinemaId,movieId);
    }
    /*
    * @Author: xz
    * @Description:获取影院
    * @Date: 2021/5/30 21:04
    * @Param:[]
    * @Return: java.util.List<com.jk.CinemaBean>
    **/
    @Override
    public List<CinemaBean> getCinema() {
        return movieDao.getCinema();
    }
    /*
    * @Author: xz
    * @Description: 获取西安市的区
    * @Date: 2021/5/30 21:13
    * @Param:[]
    * @Return: java.util.List<com.jk.AddressBean>
    **/
    @Override
    public List<AddressBean> getAddressById() {
        return movieDao.getAddressById();
    }
    /*
    * @Author: xz
    * @Description: 查询影厅
    * @Date: 2021/5/30 21:24
    * @Param:[]
    * @Return: java.util.List<com.jk.MovieHallBean>
    **/
    @Override
    public List<MovieHallBean> getHall() {
        return movieDao.getHall();
    }


}
